```python
from abc import ABC, abstractmethod
from typing import Any, Dict, Optional

from pydantic import BaseModel, Field


class BaseTool(ABC, BaseModel):
    """
    基本工具类，所有工具类的基类。

    属性:
    - name (str): 工具的名称。
    - description (str): 工具的描述。
    - parameters (Optional[dict]): 工具的参数。
    """

    name: str
    description: str
    parameters: Optional[dict] = None

    class Config:
        """允许使用任意类型作为字段。"""
        arbitrary_types_allowed = True

    async def __call__(self, **kwargs) -> Any:
        """
        执行工具，传递给定的参数。

        参数:
        - **kwargs: 传递给工具的参数。

        返回:
        - Any: 工具执行的结果。
        """
        return await self.execute(**kwargs)

    @abstractmethod
    async def execute(self, **kwargs) -> Any:
        """
        执行工具，传递给定的参数。

        参数:
        - **kwargs: 传递给工具的参数。

        返回:
        - Any: 工具执行的结果。

        注意: 这是一个抽象方法，子类必须实现它。
        """

    def to_param(self) -> Dict:
        """
        将工具转换为函数调用格式。

        返回:
        - Dict: 包含工具名称、描述和参数的字典。
        """
        return {
            "type": "function",
            "function": {
                "name": self.name,
                "description": self.description,
                "parameters": self.parameters,
            },
        }


class ToolResult(BaseModel):
    """
    表示工具执行结果的类。

    属性:
    - output (Any): 工具执行的输出结果。
    - error (Optional[str]): 工具执行过程中出现的错误信息。
    - base64_image (Optional[str]): 工具生成的 base64 编码的图片。
    - system (Optional[str]): 系统相关信息。
    """

    output: Any = Field(default=None)
    error: Optional[str] = Field(default=None)
    base64_image: Optional[str] = Field(default=None)
    system: Optional[str] = Field(default=None)

    class Config:
        """允许使用任意类型作为字段。"""
        arbitrary_types_allowed = True

    def __bool__(self):
        """
        判断 ToolResult 对象是否为真。

        返回:
        - bool: 如果任意字段有值，则返回 True，否则返回 False。
        """
        return any(getattr(self, field) for field in self.__fields__)

    def __add__(self, other: "ToolResult"):
        """
        合并两个 ToolResult 对象。

        参数:
        - other (ToolResult): 另一个 ToolResult 对象。

        返回:
        - ToolResult: 合并后的 ToolResult 对象。

        注意:
        - 如果两个对象的 base64_image 字段都有值，则抛出 ValueError。
        """
        def combine_fields(
            field: Optional[str], other_field: Optional[str], concatenate: bool = True
        ):
            if field and other_field:
                if concatenate:
                    return field + other_field
                raise ValueError("Cannot combine tool results")
            return field or other_field

        return ToolResult(
            output=combine_fields(self.output, other.output),
            error=combine_fields(self.error, other.error),
            base64_image=combine_fields(self.base64_image, other.base64_image, False),
            system=combine_fields(self.system, other.system),
        )

    def __str__(self):
        """
        返回 ToolResult 对象的字符串表示。

        返回:
        - str: 如果有错误信息，返回错误信息；否则返回输出结果。
        """
        return f"Error: {self.error}" if self.error else self.output

    def replace(self, **kwargs):
        """
        返回一个新 ToolResult 对象，用给定的字段替换原有字段。

        参数:
        - **kwargs: 需要替换的字段及其新值。

        返回:
        - ToolResult: 替换后的 ToolResult 对象。
        """
        # return self.copy(update=kwargs)
        return type(self)(**{**self.dict(), **kwargs})


class CLIResult(ToolResult):
    """
    可以作为 CLI 输出的 ToolResult。

    继承自 ToolResult，主要用于 CLI 工具的输出。
    """


class ToolFailure(ToolResult):
    """
    表示工具执行失败的 ToolResult。

    继承自 ToolResult，主要用于记录工具执行失败的情况。
    """
```